package com.mspbots.sync.callback;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mspbots.sync.callback.model.CallbackHistory;
import com.mspbots.sync.callback.model.CallbackMessage;
import com.mspbots.sync.callback.services.NoticeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * com.mspbots.sync.callback.NoticeController
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/7/12
 */
@Log4j2
@RequiredArgsConstructor
@RestController
@RequestMapping("notice/{tenant}")
public class NoticeController {

    private final Map<String, NoticeService> noticeServices;
    private final RabbitMessagingTemplate messagingTemplate;
    private final ObjectMapper objectMapper;

    @PostMapping("callback")
    public Mono<String> noticeCallback(@PathVariable Integer tenant,
                                       @RequestBody CallbackMessage callbackMessage,
                                       @RequestHeader("X-Content-Signature") String signature) throws JsonProcessingException {

        log.debug("Notice call back entry: id:{},type:{},action:{},entity:{}", callbackMessage.getId(),
                callbackMessage.getType(), callbackMessage.getAction(), callbackMessage.getEntity());

        log.debug("Callback ticket id:{},type:{}", callbackMessage.getId(), callbackMessage.getType());
        if (callbackMessage.getId() == 0) {
            return Mono.just("SUCCESS");
        }

        CallbackHistory callbackHistory = CallbackHistory.builder()
                .id(callbackMessage.getId())
                .tenantId(tenant)
                .type(callbackMessage.getType().name())
                .fromUrl(callbackMessage.getFromUrl())
                .companyId(callbackMessage.getCompanyId())
                .memberId(callbackMessage.getMemberId())
                .action(callbackMessage.getAction().name())
                .build();
        if (!StringUtils.isEmpty(callbackMessage.getEntity())) {
            callbackHistory.setEntity(this.objectMapper.readValue(callbackMessage.getEntity(), JsonNode.class));
        }

        this.messagingTemplate.convertAndSend("callback.history", callbackHistory);

        return this.noticeServices.get(callbackMessage.getType().name())
                .sender(tenant, callbackMessage).map((v) -> "SUCCESS");
    }

}
